# Copyright (c) 2007, Enrico Franchi
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of the University of California, Berkeley nor the
#       names of its contributors may be used to endorse or promote products
#       derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

from Foundation import *
from AppKit import *

from PyObjCTools import NibClassBuilder

import models
import package
import configuration
import notifications

import linguistics
from linguistics import  AVAILABLE_TAG, INSTALLED_TAG, OUTDATED_TAG, INVALID_TAG

class PortsDataSource(NibClassBuilder.AutoBaseClass):
    def init(self):
        self.available_model = models.AvailablePortsModel.alloc().initWithPath_(configuration.port_path())
        self.installed_model = models.InstalledPortsModel.alloc().initWithPath_(configuration.port_path())
        self.outdated_model  = models.OutdatedPortsModel.alloc().initWithPath_(configuration.port_path())
        self.available_void  = True
        self.installed_void  = True
        self.outdated_void   = True
        return self

    def awakeFromNib(self):
        for tag in linguistics.tags:
            notifications.registerForRefreshedNotifications(self, 'refreshView:', tag)
        notifications.registerForRefreshNotifications(self.available_model, 'refresh:', self)
        notifications.registerForRefreshNotifications(self.installed_model, 'refresh:', self)
        notifications.registerForRefreshNotifications(self.outdated_model,  'refresh:', self)
        
    def setFilter(self, l_filter, kind):
        model = getattr(self, kind + '_model')
        model.setFilter(l_filter)

    def refreshModel(self, kind):
        setattr(self, kind + '_void', False)      
        notifications.askRefreshModel(kind, self)
        
    def refreshView_(self, notification):
        # shouldn't we use a userInfo dictionary?
        tag = notification.name()[10:-10].lower()
        self.refreshView(tag)
        
    def refreshView(self, kind):
        tableView = getattr(self, kind + 'TableView')
        tableView.reloadData()
        
    def tableView_shouldEditTableColumn_row_(self, aTableView, aTableColumn, rowIndex):
        return False

    def tableViewSelectionDidChange_(self, notification):
        changedTable = notification.object()
        if changedTable.numberOfSelectedRows == 0:
            self.appDelegate.closeDrawer()
        elif changedTable.numberOfSelectedRows() == 1:
            self.appDelegate.openDrawer()
            index = changedTable.selectedRow()
            tag = self.tagByTable(changedTable)
            model = getattr(self, tag + '_model')
            self.portInfoController.selectPort(model[index, 0])
        elif changedTable.numberOfSelectedRows() > 1:
            self.appDelegate.closeDrawer()
            
    def numberOfRowsInTableView_(self, table):
        tag = self.tagByTable(table)
        try:
            model = getattr(self, tag + '_model')
            return len(model)
        except AttributeError:
            return 0

    def tableView_objectValueForTableColumn_row_(self, table, tableColumn, row):
        tag   = self.tagByTable(table)
        model = getattr(self, tag + '_model')
        col   = tableColumn.identifier().intValue()
        val   = model[row, col]
        # print "%s[%i][%i] = %s" % (tag, row, col, val)
        return val
        
    def tagByTable(self, table):
        if table == self.availableTableView:
            return AVAILABLE_TAG
        if table == self.installedTableView:
            return INSTALLED_TAG
        if table == self.outdatedTableView:
            return OUTDATED_TAG
        return INVALID_TAG
        
    def portNameByRow(self, table, row):
        if isinstance(table, NSTableView):
            tag = self.tagByTable(table)
        else:
            tag = table
        model = getattr(self, tag + '_model')
        return model[row][0]
        
    def portVersionByRow(self, table, row):
        if isinstance(table, NSTableView):
            tag = self.tagByTable(table)
        else:
            tag = table
        model = getattr(self, tag + '_model')
        return model[row][1]    
    
